# coding = utf-8
from rest_framework import serializers, exceptions, status
from rest_framework.serializers import Serializer, ModelSerializer, ListSerializer
from users.api.authentication import authenticate
from users.api.utils import jwt_payload_handler, jwt_encode_handler, login_record

from users.models import UserInfo, Role, Permission, UserLog


class JSONWebTokenSerializer(Serializer):
    """
    JWT 信息
    """
    username = serializers.CharField()
    password = serializers.CharField(write_only=True)

    def validate(self, data):
        if all(data):
            user = authenticate(**data)

            if user:
                payload = jwt_payload_handler(user)
                return {
                    'token': jwt_encode_handler(payload),
                    'user': user
                }
            else:
                msg = {
                    "status_code": status.HTTP_401_UNAUTHORIZED,
                    "message": "用户或密码错误!",
                }

                login_record(**self.initial_data, desc="登录失败")

                raise exceptions.AuthenticationFailed(msg)

        else:
            msg = {
                "status_code": status.HTTP_401_UNAUTHORIZED,
                "message": "校验错误,必须包括用户和密码",
            }

            login_record(**self.initial_data, desc="登录失败")

            raise exceptions.AuthenticationFailed(msg)


class PasswordChangeSerializer(Serializer):
    """
    JWT 信息
    """
    username = serializers.CharField()
    password = serializers.CharField()
    newpassword = serializers.CharField()
    repassword = serializers.CharField()

    def validate(self, data):

        if all(data):
            user = authenticate(**data)
            if user:
                newpassword = data.get("newpassword")
                repassword = data.get("repassword")
                if newpassword == repassword:
                    user.set_password(newpassword)
                    user.save()
                    return {
                        'user': user,
                    }
                else:
                    msg = {
                        "status_code": status.HTTP_401_UNAUTHORIZED,
                        "message": "两次密码不一致!",
                    }
                    raise exceptions.AuthenticationFailed(msg)
            else:
                msg = {
                    "status_code": status.HTTP_401_UNAUTHORIZED,
                    "message": "用户或密码错误!",
                }
                raise exceptions.AuthenticationFailed(msg)
        else:
            msg = {
                "status_code": status.HTTP_401_UNAUTHORIZED,
                "message": "校验错误,必须包括用户和密码",
            }
            raise exceptions.AuthenticationFailed(msg)


class PasswordSerializer(Serializer):
    """
    密码修改
    """
    id = serializers.IntegerField()
    name = serializers.CharField()
    password = serializers.CharField()
    repassword = serializers.CharField()

    def validate(self, data):

        if all(data):
            name = data.get("name")
            user = UserInfo.objects.filter(name=name).first()
            if user:
                newpassword = data.get("password")
                repassword = data.get("repassword")
                if newpassword == repassword:
                    user.set_password(newpassword)
                    user.save()
                    return {
                        'user': user,
                    }
                else:
                    msg = {
                        "status_code": status.HTTP_401_UNAUTHORIZED,
                        "message": "两次密码不一致!",
                    }
                    raise exceptions.AuthenticationFailed(msg)
            else:
                msg = {
                    "status_code": status.HTTP_401_UNAUTHORIZED,
                    "message": "用户不存在!",
                }
                raise exceptions.AuthenticationFailed(msg)
        else:
            msg = {
                "status_code": status.HTTP_401_UNAUTHORIZED,
                "message": "校验错误,必须包括用户和密码",
            }
            raise exceptions.AuthenticationFailed(msg)


class UserInfoSerializer(ModelSerializer):
    """
    用户信息
    """
    password = serializers.CharField(label='密码', write_only=True)
    avatar = serializers.ImageField(allow_null=True, label='头像', max_length=100, required=False, read_only=True)
    create_at = serializers.DateTimeField(read_only=True)
    last_login = serializers.DateTimeField(read_only=True)

    class Meta:
        model = UserInfo
        fields = "__all__"
        # exclude = ["avatar"]


class UserInfoReadOnlySerializer(ModelSerializer):
    """
    用户信息
    """
    password = serializers.CharField(label='密码', write_only=True)
    roles = serializers.StringRelatedField(label='所属角色', many=True)

    class Meta:
        model = UserInfo
        fields = "__all__"
        # exclude = ["avatar"]


class RoleSerializer(ModelSerializer):
    """
    角色信息
    """

    class Meta:
        model = Role
        fields = ["id", "name", "comment", "permissions", "only_own"]
        # depth = 1


class RoleListSerializer(ModelSerializer):
    """
    角色列表信息
    """
    class Meta:
        model = Role
        fields = ["id", "name"]


class RolePermsSerializer(ModelSerializer):
    """
    角色权限信息
    """
    children = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = Permission
        fields = ['id', 'name', 'path', 'level', 'parent',  'sort', 'icon', 'children']

    def get_children(self, obj):
        if isinstance(self.context["request"].user, UserInfo):
            # 超级用户
            if self.context["request"].user.is_superuser:
                return self.__class__(obj.children.all(), many=True, context=self.context).data

            perms = self.context.get("perms", None)
            if not perms:
                user = self.context["request"].user
                perms = user.roles.filter(permissions__id__isnull=False).values("permissions")
                self.context["perms"] = perms
            perms_list = obj.children.filter(id__in=perms)
            return self.__class__(perms_list, many=True, context=self.context).data
        else:
            return None


class PermissionTreeSerializer(ModelSerializer):
    """
    权限信息
    """
    children = serializers.SerializerMethodField(read_only=True)
    # hasChildren = serializers.BooleanField(read_only=True)

    class Meta:
        model = Permission
        fields = ['id', 'name', 'path', 'level', 'parent', 'parent_path', 'sort', 'icon', 'children']
        # depth = 1

    def get_children(self, obj):
        if obj.children.count() == 0:
            return ''

        return self.__class__(obj.children.all(), many=True).data


class PermissionListSerializer(ModelSerializer):
    """
    权限信息
    """
    parent_name = serializers.CharField(source="parent.name", read_only=True)

    class Meta:
        model = Permission
        fields = ['id', 'name', 'path', 'level', 'parent', 'parent_name', 'parent_path', 'icon', 'sort']


class UserLogSerializer(ModelSerializer):
    """
    用户登录信息
    """
    class Meta:
        model = UserLog
        fields = "__all__"
